package com.rybbaby.tss.core.verifier;

import com.rybbaby.tss.core.annotation.validator.IPValidator.IPType;

/**
 * @description IP地址验证器
 * 
 * @author 谢进伟
 * 
 * @createDate 2016年3月31日 下午1:51:49
 */
public class IPVerifier extends AbstractVerifier {
	
	/**
	 * IP类型
	 * 
	 * @return
	 */
	public IPType [] iptype = {IPType.IPV4 , IPType.IPV6};
	
	private static final String IPV4REGEX = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
	private static final String IPV6REGEX = "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$";
	
	/**
	 * 获取IP类型
	 * 
	 * @return IP类型
	 */
	public IPType [] getIptype() {
		return this.iptype;
	}
	
	/**
	 * 设置IP类型
	 * 
	 * @param iptype
	 *            IP类型
	 */
	public void setIptype(IPType [] iptype) {
		this.iptype = iptype;
	}
	
	/**
	 * 是否允许为空值
	 * 
	 * @return
	 */
	public boolean nullable = true;
	
	/**
	 * 获取 是否允许为空值
	 * 
	 * @return 是否允许为空值
	 */
	public boolean isNullable() {
		return this.nullable;
	}
	
	/**
	 * 设置 是否允许为空值
	 * 
	 * @param nullable
	 *            是否允许为空值
	 */
	public void setNullable(boolean nullable) {
		this.nullable = nullable;
	}
	
	@Override
	public boolean validate(Object params) {
		return validate(params , nullable , null , new ValidationRule() {
			
			@Override
			public boolean check(Object params) {
				return checkIP(params + "");
			}
		});
	}
	
	private boolean checkIP(String value) {
		boolean result_ipv4 = true , result_ipv6 = true;
		for(IPType it : iptype) {
			if(it == IPType.IPV4) {
				result_ipv4 = value.matches(IPV4REGEX);
			} else if(it == IPType.IPV6) {
				result_ipv6 = value.matches(IPV6REGEX);
			}
		}
		return result_ipv4 || result_ipv6;
	}
	
}
